package com.cty.bio;

import com.cty.utils.Gen;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Auther: cty
 * @Date: 2020/4/16 23:30
 * @Description: BIO服务器端
 * BIO Blocking IO 同步阻塞的编程方式
 *
 * 一次IO操作包括“等待数据”和“操作数据”两个阶段。
 *      对于写操作：
 *          等待数据->准备好待写出的数据
 *          操作数据->调用写方法将准备好的数据写入与远程连接的通道
 *
 * @version: 1.0
 */
public class BIOServer {
    public static void main(String[] args) {

        int port = Gen.genPort(args);
        ServerSocket server = null;

        try {
            // 1 创建服务器端
            server = new ServerSocket(port);
            System.out.println("Server started!");

            while(true){
                // 2 服务器端阻塞式等待与客户端建立连接
                Socket client = server.accept();
                new Thread(new Handler(client)).start();
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 创建线程对象
 */
class Handler implements Runnable{
    private Socket socket;

    public Handler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        System.out.println("Server connected a Client!");
        BufferedReader reader = null;
        PrintWriter writer = null;
        try {
            // 获取连接IO，并选择合适的流
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
            writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));

            // 操作流
            while (true){
                // 读取来自客户端的输入数据
                System.out.println("Server reading...");  // 等待客户端发送数据
                String receive = reader.readLine();  // 【阻塞方法】
                System.out.println("Client: "+receive);

                // 向客户端写出数据
                writer.println("Server received: "+receive);
                writer.flush();
            }

        } catch (IOException e) {
//            e.printStackTrace();
            System.out.println("Connection reset!");
        }finally {
            // 释放流
            if(null!=writer){
                writer.close();
            }
            if(null!=reader){
                reader.close();
            }
        }
    }
}
